<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>src/node/class.node.button.js - sceneGraph.js</title>
    <link rel="stylesheet" href="http://yui.yahooapis.com/3.9.1/build/cssgrids/cssgrids-min.css">
    <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
    <link rel="stylesheet" href="../assets/css/main.css" id="site_styles">
    <link rel="shortcut icon" type="image/png" href="../assets/favicon.png">
    <script src="http://yui.yahooapis.com/combo?3.9.1/build/yui/yui-min.js"></script>
</head>
<body class="yui3-skin-sam">

<div id="doc">
    <div id="hd" class="yui3-g header">
        <div class="yui3-u-3-4">
            
                <h1><img src="../../logo/logoCGSG_256x57.png" title="sceneGraph.js"></h1>
            
        </div>
        <div class="yui3-u-1-4 version">
            <em>API Docs for: v2.1.0</em>
        </div>
    </div>
    <div id="bd" class="yui3-g">

        <div class="yui3-u-1-4">
            <div id="docs-sidebar" class="sidebar apidocs">
                <div id="api-list">
    <h2 class="off-left">APIs</h2>
    <div id="api-tabview" class="tabview">
        <ul class="tabs">
            <li><a href="#api-classes">Classes</a></li>
            <li><a href="#api-modules">Modules</a></li>
        </ul>

        <div id="api-tabview-filter">
            <input type="search" id="api-filter" placeholder="Type to filter APIs">
        </div>

        <div id="api-tabview-panel">
            <ul id="api-classes" class="apis classes">
            
                <li><a href="../classes/CGSG.html">CGSG</a></li>
            
                <li><a href="../classes/CGSGAccordion.html">CGSGAccordion</a></li>
            
                <li><a href="../classes/CGSGAnimationManager.html">CGSGAnimationManager</a></li>
            
                <li><a href="../classes/CGSGAnimationMethod.html">CGSGAnimationMethod</a></li>
            
                <li><a href="../classes/CGSGBindEntry.html">CGSGBindEntry</a></li>
            
                <li><a href="../classes/CGSGButtonMode.html">CGSGButtonMode</a></li>
            
                <li><a href="../classes/CGSGCollisionGhostOnDemandTester.html">CGSGCollisionGhostOnDemandTester</a></li>
            
                <li><a href="../classes/CGSGCollisionManager.html">CGSGCollisionManager</a></li>
            
                <li><a href="../classes/CGSGCollisionMethod.html">CGSGCollisionMethod</a></li>
            
                <li><a href="../classes/CGSGCollisionRegionTester.html">CGSGCollisionRegionTester</a></li>
            
                <li><a href="../classes/CGSGCollisionTesterFactory.html">CGSGCollisionTesterFactory</a></li>
            
                <li><a href="../classes/CGSGColor.html">CGSGColor</a></li>
            
                <li><a href="../classes/CGSGCSSManager.html">CGSGCSSManager</a></li>
            
                <li><a href="../classes/CGSGDimension.html">CGSGDimension</a></li>
            
                <li><a href="../classes/CGSGEvent.html">CGSGEvent</a></li>
            
                <li><a href="../classes/CGSGEventManager.html">CGSGEventManager</a></li>
            
                <li><a href="../classes/CGSGHandleBox.html">CGSGHandleBox</a></li>
            
                <li><a href="../classes/CGSGImgManager.html">CGSGImgManager</a></li>
            
                <li><a href="../classes/CGSGInterpolator.html">CGSGInterpolator</a></li>
            
                <li><a href="../classes/CGSGInterpolatorLinear.html">CGSGInterpolatorLinear</a></li>
            
                <li><a href="../classes/CGSGInterpolatorTCB.html">CGSGInterpolatorTCB</a></li>
            
                <li><a href="../classes/CGSGKeyFrame.html">CGSGKeyFrame</a></li>
            
                <li><a href="../classes/CGSGMap.html">CGSGMap</a></li>
            
                <li><a href="../classes/CGSGMask.html">CGSGMask</a></li>
            
                <li><a href="../classes/CGSGMaskCache.html">CGSGMaskCache</a></li>
            
                <li><a href="../classes/CGSGMaskClip.html">CGSGMaskClip</a></li>
            
                <li><a href="../classes/CGSGMath.html">CGSGMath</a></li>
            
                <li><a href="../classes/CGSGNode.html">CGSGNode</a></li>
            
                <li><a href="../classes/CGSGNodeButton.html">CGSGNodeButton</a></li>
            
                <li><a href="../classes/CGSGNodeCircle.html">CGSGNodeCircle</a></li>
            
                <li><a href="../classes/CGSGNodeColorPicker.html">CGSGNodeColorPicker</a></li>
            
                <li><a href="../classes/CGSGNodeCurveTCB.html">CGSGNodeCurveTCB</a></li>
            
                <li><a href="../classes/CGSGNodeDomElement.html">CGSGNodeDomElement</a></li>
            
                <li><a href="../classes/CGSGNodeEllipse.html">CGSGNodeEllipse</a></li>
            
                <li><a href="../classes/CGSGNodeImage.html">CGSGNodeImage</a></li>
            
                <li><a href="../classes/CGSGNodeLine.html">CGSGNodeLine</a></li>
            
                <li><a href="../classes/CGSGNodeSlider.html">CGSGNodeSlider</a></li>
            
                <li><a href="../classes/CGSGNodeSliderHandle.html">CGSGNodeSliderHandle</a></li>
            
                <li><a href="../classes/CGSGNodeSprite.html">CGSGNodeSprite</a></li>
            
                <li><a href="../classes/CGSGNodeSquare.html">CGSGNodeSquare</a></li>
            
                <li><a href="../classes/CGSGNodeTabMenu.html">CGSGNodeTabMenu</a></li>
            
                <li><a href="../classes/CGSGNodeText.html">CGSGNodeText</a></li>
            
                <li><a href="../classes/CGSGNodeWebview.html">CGSGNodeWebview</a></li>
            
                <li><a href="../classes/CGSGParticle.html">CGSGParticle</a></li>
            
                <li><a href="../classes/CGSGParticleEmitter.html">CGSGParticleEmitter</a></li>
            
                <li><a href="../classes/CGSGParticleSystem.html">CGSGParticleSystem</a></li>
            
                <li><a href="../classes/CGSGPickNodeMethod.html">CGSGPickNodeMethod</a></li>
            
                <li><a href="../classes/CGSGPosition.html">CGSGPosition</a></li>
            
                <li><a href="../classes/CGSGRegion.html">CGSGRegion</a></li>
            
                <li><a href="../classes/CGSGRotation.html">CGSGRotation</a></li>
            
                <li><a href="../classes/CGSGScale.html">CGSGScale</a></li>
            
                <li><a href="../classes/CGSGSceneGraph.html">CGSGSceneGraph</a></li>
            
                <li><a href="../classes/CGSGSection.html">CGSGSection</a></li>
            
                <li><a href="../classes/CGSGTimeline.html">CGSGTimeline</a></li>
            
                <li><a href="../classes/CGSGTraverser.html">CGSGTraverser</a></li>
            
                <li><a href="../classes/CGSGVector2D.html">CGSGVector2D</a></li>
            
                <li><a href="../classes/CGSGView.html">CGSGView</a></li>
            
                <li><a href="../classes/CGSGWEBVIEWMODE.html">CGSGWEBVIEWMODE</a></li>
            
                <li><a href="../classes/CGSGWrapMode.html">CGSGWrapMode</a></li>
            
                <li><a href="../classes/GLOBAL_CONSTANTS.html">GLOBAL_CONSTANTS</a></li>
            
                <li><a href="../classes/GLOBAL_METHODS.html">GLOBAL_METHODS</a></li>
            
                <li><a href="../classes/GLOBAL_PROPERTIES.html">GLOBAL_PROPERTIES</a></li>
            
                <li><a href="../classes/UTIL_ARRAY.html">UTIL_ARRAY</a></li>
            
                <li><a href="../classes/WUICCGSGNodeImageFactory.html">WUICCGSGNodeImageFactory</a></li>
            
            </ul>

            <ul id="api-modules" class="apis modules">
            
                <li><a href="../modules/Animation.html">Animation</a></li>
            
                <li><a href="../modules/Collision.html">Collision</a></li>
            
                <li><a href="../modules/Math.html">Math</a></li>
            
                <li><a href="../modules/Node.html">Node</a></li>
            
                <li><a href="../modules/ParticleSystem.html">ParticleSystem</a></li>
            
                <li><a href="../modules/Scene.html">Scene</a></li>
            
                <li><a href="../modules/Util.html">Util</a></li>
            
            </ul>
        </div>
    </div>
</div>

            </div>
        </div>
        <div class="yui3-u-3-4">
                <div id="api-options">
        Show:
        <label for="api-show-inherited">
            <input type="checkbox" id="api-show-inherited" checked>
            Inherited
        </label>

        <label for="api-show-protected">
            <input type="checkbox" id="api-show-protected">
            Protected
        </label>

        <label for="api-show-private">
            <input type="checkbox" id="api-show-private">
            Private
        </label>
        <label for="api-show-deprecated">
            <input type="checkbox" id="api-show-deprecated">
            Deprecated
        </label>

    </div>


            <div class="apidocs">
                <div id="docs-main">
                    <div class="content">
                        <h1 class="file-heading">File: src/node/class.node.button.js</h1>

<div class="file">
    <pre class="code prettyprint linenums">
/*
 * Copyright (c) 2014 Gwennael Buchet
 *
 * License/Terms of Use
 *
 * Permission is hereby granted, free of charge and for the term of intellectual property rights on the Software, to any
 * person obtaining a copy of this software and associated documentation files (the &quot;Software&quot;), to use, copy, modify
 * and propagate free of charge, anywhere in the world, all or part of the Software subject to the following mandatory conditions:
 *
 *   •    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 *
 *  Any failure to comply with the above shall automatically terminate the license and be construed as a breach of these
 *  Terms of Use causing significant harm to Gwennael Buchet.
 *
 *  THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 *  WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
 *  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 *  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 *  Except as contained in this notice, the name of Gwennael Buchet shall not be used in advertising or otherwise to promote
 *  the use or other dealings in this Software without prior written authorization from Gwennael Buchet.
 *
 *  These Terms of Use are subject to French law.
 */

var CGSGNodeButtonProps = CGSGObject.extend(
    {
        initialize: function () {
            this.cls = [];
            this.firstColor = &quot;&quot;;
            this.lastColor = &quot;&quot;;
            this.shadowColor = &quot;&quot;;
            this.radius = 0;

            this.lineWidth = 0;
            this.lineColor = &quot;&quot;;
            this.paddingV = 10;
            this.paddingH = 10;

            /**
             * @property txtNode
             * @type {CGSGNodeText}
             */
            this.txtNode = new CGSGNodeText(0, 0, &quot;&quot;);
            /**
             * Slice in the image for the icon
             * @property slice
             * @type {CGSGRegion}
             * @default null
             */
            this.slice = null;
            /**
             * @property icon
             * @type {CGSGNodeImage}
             * @default null
             */
            this.icon = null;
            /**
             * Computed dimensions of the button in the 3 modes.
             * Do not edit manually!
             * @property _dimensions
             * @type {Array}
             * @private
             */
            this.dimension = new CGSGDimension(10, 10);

            this._invalSize = true;
        }

    }
);

/**
 * List the modes for a button : NORMAL, OVER, DEACTIVATED, SELECTED.
 * @class CGSGButtonMode
 * @type {Object}
 * @author Gwennael Buchet (gwennael.buchet@gmail.com)
 * @example
 *      myTextNode.setMode(CGSGButtonMode.DEACTIVATED);
 */
var CGSGButtonMode = {
    /**
     * @property NORMAL
     */
    NORMAL     : {
        id         : 0,
        isClickable: true
    },
    /**
     * @property OVER
     */
    OVER       : {
        id         : 1,
        isClickable: true
    },
    /**
     * @property DEACTIVATED
     */
    DEACTIVATED: {
        id         : 2,
        isClickable: false
    },

    /**
     * @property SELECTED
     */
    SELECTED: {
        id         : 3,
        isClickable: true
    }
};

var CGSGPositionMode = {
    /**
     * @property TOP
     */
    TOP: {index      : 0, decalX: 0, decalY: -1, dt: 1, dy: 1,
        computeWidth : function (item1, item2) {
            return Math.max(item1, item2);
        },
        computeHeight: function (item1, item2) {
            return 0;
        }},

    /**
     * @property BOTTOM
     */
    BOTTOM: {index   : 1, decalX: 0, decalY: 1, dt: 0, dy: 1,
        computeWidth : function (item1, item2) {
            return Math.max(item1, item2);
        },
        computeHeight: function (item1, item2) {
            return 0;
        }},
    /**
     * @property LEFT
     */
    LEFT  : {index   : 2, decalX: -1, decalY: 0, dt: 0, dy: 0,
        computeWidth : function (item1, item2) {
            return 0;
        },
        computeHeight: function (item1, item2) {
            return Math.max(item1, item2);
        }},
    /**
     * @property RIGHT
     */
    RIGHT : {index   : 3, decalX: 1, decalY: 0, dt: 1, dy: 0,
        computeWidth : function (item1, item2) {
            return 0;
        },
        computeHeight: function (item1, item2) {
            return Math.max(item1, item2);
        }}
};

/**
 * A CGSGNodeButton represent a basic square
 *
 * @class CGSGNodeButton
 * @module Node
 * @extends CGSGNode
 * @constructor
 * @param {Number} x Relative position on X
 * @param {Number} y Relative position on Y
 * @param {String} text
 * @type {CGSGNodeButton}
 * @author Gwennael Buchet (gwennael.buchet@gmail.com)
 */
var CGSGNodeButton = CGSGNode.extend(
    {
        initialize: function (x, y, text) {
            /**
             * A properties group for each mode.
             * Index in this array corresponds to the id of the mode
             * @property _props
             * @type {CGSGNodeButtonProps[]}
             * @private
             */
            this._props = [
                new CGSGNodeButtonProps(),
                new CGSGNodeButtonProps(),
                new CGSGNodeButtonProps(),
                new CGSGNodeButtonProps()
            ];

            this._super(x, y);

            this._needRedraw = false;

            /**
             * @property _pictoPosition
             * @default CGSGPositionMode.LEFT
             * @type {CGSGPositionMode}
             * @private
             */
            this._pictoPosition = CGSGPositionMode.LEFT;

            /**
             * Distance between the picto and the text
             * @property _distancePictoText
             * @default 10
             * @type {Number}
             * @private
             */
            this._distancePictoText = 10;

            /**
             * Fake canvases to pre-render static display
             * @property _tmpCanvas
             * @type {Array}
             * @private
             */
            this._tmpCanvases = [document.createElement(&#x27;canvas&#x27;),
                                 document.createElement(&#x27;canvas&#x27;),
                                 document.createElement(&#x27;canvas&#x27;),
                                 document.createElement(&#x27;canvas&#x27;)];

            /**
             * @property classType
             * @readonly
             * @type {String}
             * @default &quot;CGSGNodeButton&quot;
             */
            this.classType = &quot;CGSGNodeButton&quot;;

            /**
             * Current mode of the button
             * @property _currentMode
             * @type {CGSGButtonMode}
             * @default CGSGButtonMode.NORMAL
             * @private
             */
            this._currentMode = CGSGButtonMode.NORMAL;

            this.setMode(this._currentMode);

            this.setClassFor(&quot;cgsg-button&quot;, CGSGButtonMode.NORMAL);
            this.setClassFor(&quot;cgsg-button-over&quot;, CGSGButtonMode.OVER);
            this.setClassFor(&quot;cgsg-button-deactivated&quot;, CGSGButtonMode.DEACTIVATED);
            this.setClassFor(&quot;cgsg-button-selected&quot;, CGSGButtonMode.SELECTED);
            this._props[0].txtNode.addClass(&quot;cgsg-button-text&quot;);
            this._props[1].txtNode.addClass(&quot;cgsg-button-over-text&quot;);
            this._props[2].txtNode.addClass(&quot;cgsg-button-deactivated-text&quot;);
            this._props[3].txtNode.addClass(&quot;cgsg-button-selected-text&quot;);

            this.setTexts(text);

            var that = this;
            this.onMouseOver = function (e) {
                if (that.getMode() == CGSGButtonMode.NORMAL) {
                    that.setMode(CGSGButtonMode.OVER);
                }
            };

            this.onMouseOut = function (e) {
                if (that.getMode() == CGSGButtonMode.OVER) {
                    that.setMode(CGSGButtonMode.NORMAL);
                }
            };

            /*CGSG.eventManager.bindHandler(this, cgsgEventTypes.ON_FREE, (function(e) {
             this.setMode(CGSGButtonMode.SELECTED);
             }).bind(this));*/

            this._isInitialized = true;
        },

        /**
         * Change the position of the picto : CGSGPositionMode.LEFT, CGSGPositionMode.TOP, CGSGPositionMode.RIGHT, CGSGPositionMode.BOTTOM
         * @method setPictoPosition
         * @param {CGSGPositionMode} p
         */
        setPictoPosition: function (p) {
            this._pictoPosition = p;
            this.forceRedraw();
        },

        /**
         * Because a button got 4 modes it also got 4 CSS management
         * @method setClassFor
         * @param cls {String}
         * @param mode {CGSGButtonMode}
         */
        setClassFor: function (cls, mode) {
            this._props[mode.id].cls = [];
            this._props[mode.id].cls.push(cls);

            this._props[mode.id]._invalSize = false;
            this._needRedraw = false;
            this._loadAttrs(mode);
            this._initShape(mode);
        },

        /**
         * Set the same CSS class for all 4 modes
         * @method setClass
         * @param cls {String}
         */
        setClass: function (cls) {
            this._clearAllCls();
            this._props[CGSGButtonMode.NORMAL.id].cls.push(cls);
            this._props[CGSGButtonMode.OVER.id].cls.push(cls);
            this._props[CGSGButtonMode.DEACTIVATED.id].cls.push(cls);
            this._props[CGSGButtonMode.SELECTED.id].cls.push(cls);

            this.invalidateTheme();
        },

        /**
         * @method setClasses
         * @param clss {Array} Array of CSS class name
         */
        setClasses: function (clss) {
            this._clearAllCls();
            this._props[CGSGButtonMode.NORMAL.id].cls.push(clss[0]);
            this._props[CGSGButtonMode.OVER.id].cls.push(clss[1]);
            this._props[CGSGButtonMode.DEACTIVATED.id].cls.push(clss[2]);
            this._props[CGSGButtonMode.SELECTED.id].cls.push(clss[3]);
            this.invalidateTheme();
        },

        _clearAllCls: function () {
            this._props[CGSGButtonMode.NORMAL.id].cls = [];
            this._props[CGSGButtonMode.OVER.id].cls = [];
            this._props[CGSGButtonMode.DEACTIVATED.id].cls = [];
            this._props[CGSGButtonMode.SELECTED.id].cls = [];
        },

        /**
         * Add CSS class for this node and for this mode only (not for bounding box, use &#x27;setClassBBox&#x27; instead).
         * CSS class must define attributes used by this node.
         * @method addClassFor
         * @param {String} cls
         * @param mode {CGSGButtonMode}
         */
        addClassFor: function (cls, mode) {
            this._props[mode.id].cls.push(cls);

            this._props[mode.id]._invalSize = false;
            this._needRedraw = false;
            this._loadAttrs(mode);
            this._initShape(mode);
        },

        /**
         * Add CSS class for this node for all 4 modes (not for bounding box, use &#x27;setClassBBox&#x27; instead).
         * CSS class must define attributes used by this node.
         * @method addClass
         * @param {String} cls
         */
        addClass: function (cls) {
            this._props[CGSGButtonMode.NORMAL.id].cls.push(cls);
            this._props[CGSGButtonMode.OVER.id].cls.push(cls);
            this._props[CGSGButtonMode.DEACTIVATED.id].cls.push(cls);
            this._props[CGSGButtonMode.SELECTED.id].cls.push(cls);

            this.invalidateTheme();
        },

        /**
         * Add CSS class for this node for all 4 modes (not for bounding box, use &#x27;setClassBBox&#x27; instead).
         * CSS class must define attributes used by this node.
         * @method addClasses
         * @param {Array} clss
         */
        addClasses: function (clss) {
            this._props[CGSGButtonMode.NORMAL.id].cls.push(clss[0]);
            this._props[CGSGButtonMode.OVER.id].cls.push(clss[1]);
            this._props[CGSGButtonMode.DEACTIVATED.id].cls.push(clss[2]);
            this._props[CGSGButtonMode.SELECTED.id].cls.push(clss[3]);

            this.invalidateTheme();
        },

        /**
         * remove CSS class for this node and for this mode only (not for bounding box, use &#x27;setClassBBox&#x27; instead).
         * @method removeClassFor
         * @param {String} cls
         * @param {CGSGButtonMode} mode
         */
        removeClassFor: function (cls, mode) {
            this._props[mode.id].cls = this._props[mode.id].cls.without(cls);
            this.forceRedraw();
            this._loadAttrs(mode);
            this._initShape(mode);
        },

        /**
         * remove CSS class for this node for all 4 modes (not for bounding box, use &#x27;setClassBBox&#x27; instead).
         * @method removeClass
         * @param {String} cls
         */
        removeClass: function (cls) {
            this._props[CGSGButtonMode.NORMAL.id].cls = this._props[CGSGButtonMode.NORMAL.id].without(cls);
            this._props[CGSGButtonMode.OVER.id].cls = this._props[CGSGButtonMode.OVER.id].without(cls);
            this._props[CGSGButtonMode.DEACTIVATED.id].cls = this._props[CGSGButtonMode.DEACTIVATED.id].without(cls);
            this._props[CGSGButtonMode.SELECTED.id].cls = this._props[CGSGButtonMode.SELECTED.id].without(cls);

            this.invalidateTheme();
        },

        /**
         * @method setImageFor
         * @param img {Image}
         * @param mode {CGSGButtonMode}
         */
        setImageFor: function (img, mode) {
            this._props[mode.id].icon.setImage(img);
        },

        /**
         * Set the image for the picto
         * @method setImage
         * @param {Image} img
         */
        setImage: function (img) {
            this._checkIcon();

            this.setImageFor(img, CGSGButtonMode.NORMAL);
            this.setImageFor(img, CGSGButtonMode.OVER);
            this.setImageFor(img, CGSGButtonMode.DEACTIVATED);
            this.setImageFor(img, CGSGButtonMode.SELECTED);

            this._needRedraw = true;
        },

        /**
         * Set the URL for the icon for all modes
         * @method setImageURL
         * @param url
         */
        setImageURL: function (url) {
            this._checkIcon();

            this._props[CGSGButtonMode.NORMAL.id].icon.onLoadEnd = this._onLoadImageEndAll.bind(this);
            this._props[CGSGButtonMode.NORMAL.id].icon.setURL(url);
        },

        /**
         * Set the URL for the icon for all modes
         * @method setImageURL
         * @param url
         * @param mode {CGSGButtonMode}
         */
        setImageURLFor: function (url, mode) {
            this._props[mode.id].icon.onLoadEnd = this._onLoadImageEndFor.bind(this);
            this._props[mode.id].icon.setURL(url);
        },

        _onLoadImageEndFor: function () {
            this.forceRedraw();
        },

        _onLoadImageEndAll: function () {
            var img = this._props[CGSGButtonMode.NORMAL.id].icon.getImage();
            this._props[CGSGButtonMode.OVER.id].icon.setImage(img);
            this._props[CGSGButtonMode.DEACTIVATED.id].icon.setImage(img);
            this._props[CGSGButtonMode.SELECTED.id].icon.setImage(img);

            this.forceRedraw();
        },

        /**
         * Check if icon object already exist for each mode.
         * If not, create them
         * @method _checkIcon
         * @private
         */
        _checkIcon: function () {
            this._checkIconFor(CGSGButtonMode.NORMAL);
            this._checkIconFor(CGSGButtonMode.OVER);
            this._checkIconFor(CGSGButtonMode.DEACTIVATED);
            this._checkIconFor(CGSGButtonMode.SELECTED);
        },

        /**
         * @method _checkIconFor
         * @param mode
         * @private
         */
        _checkIconFor: function (mode) {
            if (!cgsgExist(this._props[mode.id].icon)) {
                this._props[mode.id].icon = new CGSGNodeImage(0, 0, null);
            }
        },

        /**
         * Return the text of the button
         * @method getText
         * @return {Array}
         */
        getTexts: function () {
            return [CGSGButtonMode.NORMAL.props.txtNode._text, CGSGButtonMode.OVER.props.txtNode._text,
                    CGSGButtonMode.DEACTIVATED.props.txtNode._text, CGSGButtonMode.SELECTED.props.txtNode._text];
        },

        /**
         * Force this node to be fully recomputed during next frame
         * @method forceRedraw
         */
        forceRedraw: function () {
            this._needRedraw = true;

            this._props[CGSGButtonMode.NORMAL.id]._invalSize = true;
            this._props[CGSGButtonMode.OVER.id]._invalSize = true;
            this._props[CGSGButtonMode.DEACTIVATED.id]._invalSize = true;
            this._props[CGSGButtonMode.SELECTED.id]._invalSize = true;
        },

        /**
         * Set the values for text of the button
         * @method setText
         * @param valuess {Array}
         * @example
         *  button.setText([&quot;normal&quot;, &quot;over&quot;, &quot;deactivated&quot;]);
         */
        setTexts: function (valuess) {
            //if valuess is not an array, create an array of 4 times this values
            if (!cgsgIsArray(valuess)) {
                var v = valuess.toString();
                valuess = [v, v, v, v];
            }

            this._props[CGSGButtonMode.NORMAL.id].txtNode.setText(valuess[0], true);
            this._props[CGSGButtonMode.OVER.id].txtNode.setText(valuess[1], true);
            this._props[CGSGButtonMode.DEACTIVATED.id].txtNode.setText(valuess[2], true);
            this._props[CGSGButtonMode.SELECTED.id].txtNode.setText(valuess[3], true);

            this.forceRedraw();
        },

        /**
         * @method setTextClass
         * @param cls {String} CSS class name
         */
        setTextClass: function (cls) {
            this._props[CGSGButtonMode.NORMAL.id].txtNode.setClass(cls);
            this._props[CGSGButtonMode.OVER.id].txtNode.setClass(cls);
            this._props[CGSGButtonMode.DEACTIVATED.id].txtNode.setClass(cls);
            this._props[CGSGButtonMode.SELECTED.id].txtNode.setClass(cls);
            this.invalidate();
        },

        /**
         * @method setTextClasses
         * @param clss {Array} Array of CSS class name
         */
        setTextClasses: function (clss) {
            this._props[CGSGButtonMode.NORMAL.id].txtNode.setClass(clss[0]);
            this._props[CGSGButtonMode.OVER.id].txtNode.setClass(clss[1]);
            this._props[CGSGButtonMode.DEACTIVATED.id].txtNode.setClass(clss[2]);
            this._props[CGSGButtonMode.SELECTED.id].txtNode.setClass(clss[3]);
            this.invalidate();
        },

        /**
         * @method setTextClassFor
         * @param mode {CGSGButtonMode}
         * @param cls {String} CSS class name
         */
        setTextClassFor: function (cls, mode) {
            this._props[mode.id].txtNode.setClass(cls);
            this.invalidate();
        },

        /**
         * @method setFixedSize
         * @param {CGSGDimension} dim Can be null to remove fixed size
         */
        setFixedSize: function (dim) {
            this._props[CGSGButtonMode.NORMAL.id].dimension = dim;
            this._props[CGSGButtonMode.OVER.id].dimension = dim;
            this._props[CGSGButtonMode.DEACTIVATED.id].dimension = dim;
            this._props[CGSGButtonMode.SELECTED.id].dimension = dim;

            this._fixedSize = cgsgExist(dim);
            this.forceRedraw();
        },

        /**
         * Set the slices in the image for the 3 modes
         * @method setSlices
         * @param slices {Array} array of region for all 4 modes
         */
        setSlices: function (slices) {
            this._props[CGSGButtonMode.NORMAL.id].slice = slices[0];
            this._props[CGSGButtonMode.OVER.id].slice = slices[1];
            this._props[CGSGButtonMode.DEACTIVATED.id].slice = slices[2];
            this._props[CGSGButtonMode.SELECTED.id].slice = slices[3];
            this.forceRedraw();
        },

        /**
         * @method setSliceFor
         * @param slice {CGSGRegion}
         * @param mode {CGSGButtonMode}
         */
        setSliceFor: function (slice, mode) {
            this._props[mode.id].slice = slice;
            this._props[mode.id]._invalSize = true;

            this._initShape(mode);
        },

        /**
         * Reload theme (colors, ...) from loaded CSS file
         * @method invalidateTheme
         */
        invalidateTheme: function () {
            this._super();

            this._props[CGSGButtonMode.NORMAL.id].txtNode.invalidateTheme();
            this._props[CGSGButtonMode.OVER.id].txtNode.invalidateTheme();
            this._props[CGSGButtonMode.DEACTIVATED.id].txtNode.invalidateTheme();
            this._props[CGSGButtonMode.SELECTED.id].txtNode.invalidateTheme();

            //Use of &quot;this._cls&quot; class name which define the current CSS class used by this object.
            this._loadAttrs(CGSGButtonMode.NORMAL);
            this._loadAttrs(CGSGButtonMode.OVER);
            this._loadAttrs(CGSGButtonMode.DEACTIVATED);
            this._loadAttrs(CGSGButtonMode.SELECTED);

            this.invalidate();
        },

        invalidate: function () {
            if (cgsgExist(this._isInitialized) &amp;&amp; this._isInitialized === true) {
                this._initShapes();
            }
        },

        /**
         * @method _loadAttrs
         * @param mode {CGSGButtonMode}
         * @private
         */
        _loadAttrs: function (mode) {
            var cls = this._props[mode.id].cls;
            var id = mode.id;
            var prop = this._props[id];

            var fillStyle = CGSG.cssManager.getAttrInArray(cls, &quot;background&quot;);
            var lineWidth = CGSG.cssManager.getAttrInArray(cls, &quot;border-width&quot;);
            var lineColor = CGSG.cssManager.getAttrInArray(cls, &quot;border-color&quot;);
            var paddingV = CGSG.cssManager.getAttrInArray(cls, &quot;padding-top&quot;);
            var paddingH = CGSG.cssManager.getAttrInArray(cls, &quot;padding-left&quot;);
            var radius = CGSG.cssManager.getAttrInArray(cls, &quot;border-radius&quot;);
            var icon = CGSG.cssManager.getAttrInArray(cls, &quot;icon&quot;);
            if (!cgsgExist(icon)) {
                icon = CGSG.cssManager.getAttrInArray(cls, &quot;list-style-image&quot;);
            }

            //Avoid to override previous value if no one is defined now. So check existence of new one first.
            if (cgsgExist(fillStyle)) {
                //value is given as &quot;linear-gradient(rgb(150, 150, 150), rgb(127, 127, 127))&quot;.
                // Let&#x27;s convert it to 2 hex.
                var srgb1 = fillStyle.substring(fillStyle.indexOf(&quot;rgb&quot;), fillStyle.indexOf(&quot;)&quot;) + 1);
                var srgb2 = fillStyle.substring(fillStyle.lastIndexOf(&quot;rgb&quot;), fillStyle.lastIndexOf(&quot;)&quot;));
                var rgb1 = CGSGColor.fromString(srgb1);
                var rgb2 = CGSGColor.fromString(srgb2);
                prop.firstColor = CGSGColor.rgb2hex(rgb1.r, rgb1.g, rgb1.b);
                prop.lastColor = CGSGColor.rgb2hex(rgb2.r, rgb2.g, rgb2.b);
            }

            if (cgsgExist(lineColor)) {
                prop.lineColor = lineColor;
            }

            if (cgsgExist(radius)) {
                prop.radius = CGSG.cssManager.getNumber(radius);
            }

            if (cgsgExist(lineWidth)) {
                prop.lineWidth = CGSG.cssManager.getNumber(lineWidth);
            }

            if (cgsgExist(lineColor)) {
                prop.lineColor = lineColor;
            }

            if (cgsgExist(paddingV)) {
                prop.paddingV = CGSG.cssManager.getNumber(paddingV);
            }
            if (cgsgExist(paddingH)) {
                prop.paddingH = CGSG.cssManager.getNumber(paddingH);
            }

            if (cgsgExist(icon)) {
                this._checkIconFor(mode);
                this.setImageURLFor(CGSG.cssManager.getURL(icon), mode);
            }
        },

        /**
         * Increase/decrease current dimension with adding values
         * @method resizeWith
         * @param {Number} width
         * @param {Number} height
         * */
        resizeWith: function (width, height) {
            this._needRedraw = true;

            this._super(width, height);
        },

        /**
         * Pre-render the button into a temp canvas to optimize the perfs
         * @method _initShape
         * @private
         */
        _initShapes: function () {
            this._initShape(CGSGButtonMode.NORMAL);
            this._initShape(CGSGButtonMode.OVER);
            this._initShape(CGSGButtonMode.DEACTIVATED);
            this._initShape(CGSGButtonMode.SELECTED);
            this._needRedraw = false;
        },

        /**
         * Pre-render the shape for normal rendering
         * @method _initShape
         * @param mode
         * @private
         */
        _initShape: function (mode) {
            var id = mode.id;
            var prop = this._props[id];
            var txtNode = prop.txtNode;
            var tW = txtNode.getWidth(), tH = txtNode.getHeight();

            var dPT = this._distancePictoText;
            if (prop.text === &quot;&quot;) {
                dPT = 0;
            }

            var decalPictoX = 0, decalPictoY = 0;
            var wImg = 0;
            var hImg = 0;
            if (cgsgExist(prop.icon) &amp;&amp; prop.icon.isLoaded) {
                if (cgsgExist(prop.slice)) {
                    prop.icon.setSlice(prop.slice.position.x, prop.slice.position.y,
                                       prop.slice.dimension.width, prop.slice.dimension.height,
                                       true);
                }

                wImg = prop.icon.slice.dimension.width;
                hImg = prop.icon.slice.dimension.height;

                decalPictoX = (wImg + dPT) * Math.abs(this._pictoPosition.decalX);
                decalPictoY = (hImg + dPT) * Math.abs(this._pictoPosition.decalY);
            }

            if (prop._invalSize) {
                if (this._fixedSize) {
                    this.dimension.resizeTo(prop.dimension.width, prop.dimension.height);
                }
                else {
                    this.dimension.resizeTo(
                            (2 * prop.paddingH) + decalPictoX +
                            tW * Math.abs(this._pictoPosition.decalX) +
                            this._pictoPosition.computeWidth(tW, wImg),
                            (2 * prop.paddingV) + decalPictoY +
                            tH * Math.abs(this._pictoPosition.decalY) +
                            this._pictoPosition.computeHeight(tH, hImg));
                }
                prop._invalSize = false;
                this._isDimensionChanged = true;
            }
            prop.dimension = this.dimension.copy();

            this._tmpCanvases[id].width = this.dimension.width + 2 * prop.radius;
            this._tmpCanvases[id].height = this.dimension.height + 2 * prop.radius;
            var tmpContext = this._tmpCanvases[id].getContext(&#x27;2d&#x27;);

            cgsgClearContext(tmpContext);

            //render the panel
            tmpContext.save();
            {
                var r = prop.radius;
                tmpContext.translate(-r, -r);
                tmpContext.beginPath();

                tmpContext.moveTo(2 * r, r);
                tmpContext.lineTo(r + this.dimension.width - r, r);
                tmpContext.quadraticCurveTo(r + this.dimension.width,
                                            r,
                                            r + this.dimension.width,
                                            r + r);
                tmpContext.lineTo(r + this.dimension.width,
                                  r + this.dimension.height - r);
                tmpContext.quadraticCurveTo(r + this.dimension.width,
                                            r + this.dimension.height,
                                            r + this.dimension.width - r,
                                            r + this.dimension.height);
                tmpContext.lineTo(r + r,
                                  r + this.dimension.height);
                tmpContext.quadraticCurveTo(r,
                                            r + this.dimension.height,
                                            r,
                                            r + this.dimension.height - r);
                tmpContext.lineTo(r, r + r);
                tmpContext.quadraticCurveTo(r, r,
                                            r + r,
                                            r);
                tmpContext.closePath();

                /*var gradient = tmpContext.createLinearGradient(0, 0, 0, this.dimension.height);
                 gradient.addColorStop(0, prop.firstColor);
                 gradient.addColorStop(1, prop.lastColor);
                 tmpContext.fillStyle = gradient;*/
                if (!cgsgExist(prop.lastColor)) {
                    tmpContext.fillStyle = prop.firstColor;
                }
                else {
                    var gradient = tmpContext.createLinearGradient(0, 0, 0, this.dimension.height);
                    gradient.addColorStop(0, prop.firstColor);
                    gradient.addColorStop(1, prop.lastColor);
                    tmpContext.fillStyle = gradient;
                }

                if (cgsgExist(prop.shadowColor)) {
                    tmpContext.shadowColor = prop.shadowColor;
                    tmpContext.shadowBlur = 10;
                    tmpContext.shadowOffsetX = 0;
                    tmpContext.shadowOffsetY = 0;
                }

                tmpContext.fill();

                if (cgsgExist(prop.lineColor) &amp;&amp; prop.lineColor &gt; 0) {
                    tmpContext.strokeStyle = prop.lineColor;
                    tmpContext.lineWidth = prop.lineWidth;
                    tmpContext.stroke();
                }
            }
            tmpContext.restore();

            var textX = (-this._pictoPosition.decalX * decalPictoX + this.getWidth() - tW) / 2;
            var textY = (-this._pictoPosition.decalY * decalPictoY + this.getHeight() - tH) / 2;

            if (cgsgExist(prop.icon) &amp;&amp; prop.icon.isLoaded) {
                var ctX = tW / 2;

                prop.icon.translateTo(
                        textX + ctX + this._pictoPosition.decalX * (ctX + dPT + (1 - this._pictoPosition.dt) * wImg) -
                        this._pictoPosition.dy * wImg / 2,
                        (1 - this._pictoPosition.dy) * (textY + (tH - hImg) / 2)
                            + this._pictoPosition.dy * (textY - txtNode._size / 2
                                                            - this._pictoPosition.dt * (dPT + hImg) +
                                                        (1 - this._pictoPosition.dt) * (tH + dPT))
                );

                prop.icon.doRender(tmpContext);
            }

            txtNode.translateTo(textX, textY, false);
            txtNode.doRender(tmpContext);
        },

        /**
         * Switch current mode
         * @method setMode
         * @param mode
         */
        setMode: function (mode) {
            this._currentMode = mode;
            this.isClickable = mode.isClickable;
            this.dimension.resizeTo(this._props[mode.id].dimension.width, this._props[mode.id].dimension.height);
            this._isDimensionChanged = true;
        },

        /**
         * @method getMode
         * @return {CGSGButtonMode}
         */
        getMode: function () {
            return this._currentMode;
        },

        /**
         * Custom rendering
         * @method render
         * @protected
         * @param {CanvasRenderingContext2D} context the context into render the node
         * */
        render: function (context) {
            if (this._needRedraw) {
                this._initShapes();
            }

            //render the pre-rendered canvas
            context.drawImage(this._tmpCanvases[this._currentMode.id], 0, 0);
        },

        /**
         * @method copy
         * @return {CGSGNodeSquare} a copy of this node
         */
        copy: function () {
            var node = new CGSGNodeSquare(this.position.x, this.position.y, this.dimension.width,
                                          this.dimension.height);
            //call the super method
            node = this._super(node);

            node.bkgcolors = this.bkgcolors;
            node.lineColor = this.lineColor;
            node.lineWidth = this.lineWidth;
            return node;
        }
    }
);

    </pre>
</div>

                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<script src="../assets/vendor/prettify/prettify-min.js"></script>
<script>prettyPrint();</script>
<script src="../assets/js/yui-prettify.js"></script>
<script src="../assets/../api.js"></script>
<script src="../assets/js/api-filter.js"></script>
<script src="../assets/js/api-list.js"></script>
<script src="../assets/js/api-search.js"></script>
<script src="../assets/js/apidocs.js"></script>
</body>
</html>
